//
//  ViewController.m
//  testScoket
//
//  Created by eq2016 on 2019/4/29.
//  Copyright © 2019年 eq2017. All rights reserved.
//
#import <AVFoundation/AVFoundation.h>
#import "ViewController.h"
#import "NSDate+Tool.h"
#import "BSJPhotoManager.h"
#import "SVProgressHUD.h"
@interface ViewController ()<GCDAsyncSocketDelegate> {
    NSDictionary *_headerDict; //数据头部信息
    NSUInteger _length; //数据传输进度
}
@property (weak, nonatomic) IBOutlet UITextView *textView;
@property (weak, nonatomic) IBOutlet UITextField *IPTextField;
@property (weak, nonatomic) IBOutlet UITextField *msgTextField;
@property (weak, nonatomic) IBOutlet UITextField *portTextfoeld;
@property (weak, nonatomic) IBOutlet UILabel *connectStatusL;
@property (weak, nonatomic) IBOutlet UIButton *statusButton;
@property (weak, nonatomic) IBOutlet UIButton *photoBtn;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UIView *AVManageView;
@property (weak, nonatomic) IBOutlet UILabel *pingL;

@property(nonatomic, strong)GCDAsyncSocket *clientSocket;
@property (strong, nonatomic)NSTimer *longConnectTimer;
@property (strong, nonatomic)NSTimer *reconnectionTimer;
@property (strong, nonatomic)NSTimer *progressTimer;


@end

@implementation ViewController

- (GCDAsyncSocket *)clientSocket {
    if (!_clientSocket) {
        _clientSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    return _clientSocket;
}

- (void)viewDidLoad {
    [super viewDidLoad];

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [[[UIApplication sharedApplication] keyWindow] endEditing:YES];
}


//添加定时器,检测连接和重连
- (void)addTimer {
    if (!_reconnectionTimer) {
        _reconnectionTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(reconnectionConnect) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:_reconnectionTimer forMode:NSRunLoopCommonModes];
    }
    if (!_longConnectTimer) {
        _longConnectTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(longConnectToSocket) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:_longConnectTimer forMode:NSRunLoopCommonModes];
    }
    
}

//进度监听
- (void)addProgressTimer {
    _progressTimer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(progress:) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_longConnectTimer forMode:NSRunLoopCommonModes];
}

- (void)progress:(NSTimer *)timer {
    NSUInteger doneLength = 0;
    NSUInteger talLength = 0;
    float progress  = [self.clientSocket progressOfWriteReturningTag:0 bytesDone:&doneLength total:&talLength];
    NSLog(@"发送进度--%f--%ld--%ld",progress,doneLength,talLength);
    
    if (progress > 0.01 && progress < 0.99) {
        [SVProgressHUD showProgress:progress];
    }else {
        [SVProgressHUD dismiss];
        [timer invalidate];
        _progressTimer = nil;
    }
}


// 心跳连接
- (void)longConnectToSocket {
    // 发送固定格式的数据,指令@"longConnect"
    NSString *dateStr = [NSString stringWithFormat:@"date%@",[NSDate getNowTimeTimestamp3]];
    NSLog(@"当前时间:%@",dateStr);
    NSData *data = [dateStr dataUsingEncoding:NSUTF8StringEncoding];
    NSData *senData = [self sendData:data type:@"longConnect" Info:@""];
    [_clientSocket writeData:senData withTimeout:-1 tag:0];
}
//重连
- (void)reconnectionConnect {
    if (!self.clientSocket.isConnected) {
        [self connect];
    }
}

//连接服务端
- (void)connect {
    _length = 0;
    NSError *err = nil;
    NSInteger port = [self.portTextfoeld.text intValue];
    [self.clientSocket  connectToHost:self.IPTextField.text onPort:port withTimeout:30 error:&err];
    [self.clientSocket  readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
    //3.添加定时器
    [self addTimer];
}

//主动断开连接
- (void)disconnect{
    if (_clientSocket.isConnected){
        [_clientSocket disconnect];
        //主动断开连接  关闭重连定时器
        [self.reconnectionTimer invalidate];
        self.reconnectionTimer = nil;
    }
}
#pragma mark -- Click
//建立或断开连接
- (IBAction)coneClicked:(UIButton *)sender {
    if (sender.isSelected) {
        [self disconnect];
    }else {
        [self connect];
    }
}

//发送消息
- (IBAction)sendClicked:(UIButton *)sender {
    self.textView.text = [NSString stringWithFormat:@" %@\nA:%@",self.textView.text,self.msgTextField.text];
    NSData *senData = [self sendData:[self.msgTextField.text dataUsingEncoding:NSUTF8StringEncoding] type:@"text" Info:@"A"];
    [_clientSocket writeData:senData withTimeout:-1 tag:0];
    
    //清空输入框
    self.msgTextField.text = @"";
}
//发送照片
- (IBAction)senImageBtn:(UIButton *)sender {
    UIImage *image = [UIImage imageNamed:@"122.png"];
    self.imageView.image = image;
    NSData *imageData = UIImagePNGRepresentation(image);
    NSData *senData = [self sendData:imageData type:@"image" Info:@"123.png"];
    [self sendAddTimerData:senData withTimeout:-1 Tag:0];

}
//发送视频
- (IBAction)AVsenClick:(UIButton *)sender {

    NSString *path = [[NSBundle mainBundle] pathForResource:@"123" ofType:@"mp4"];
    NSData *avData = [NSData dataWithContentsOfFile:path];
    _length = avData.length;
    NSData *senData = [self sendData:avData type:@"mp4" Info:@"321.mp4"];
    [self sendAddTimerData:senData withTimeout:-1 Tag:0];
    NSLog(@"视频长度%lu",(unsigned long)avData.length);
}
//添加进度监听定时器并发送数据
- (void)sendAddTimerData:(NSData *)data withTimeout:(NSUInteger)timeout Tag:(long)tag {
    [self addProgressTimer];
    [_clientSocket writeData:data withTimeout:timeout tag:tag];
}

//数据粘包
- (NSData *)sendData:(NSData *)data type:(NSString *)typeStr Info:(NSString *)info {
    NSMutableDictionary *headerDict = [NSMutableDictionary dictionary];
    [headerDict setObject:typeStr forKey:@"type"];
    [headerDict setObject:info forKey:@"info"];
    [headerDict setObject:[NSString stringWithFormat:@"%ld",data.length] forKey:@"length"];
    NSMutableData *sendData = [NSMutableData data];
    NSData *headerData = [NSJSONSerialization dataWithJSONObject:headerDict options:NSJSONWritingPrettyPrinted error:nil];
    [sendData appendData:headerData];
    [sendData appendData:[GCDAsyncSocket CRLFData]];
    [sendData appendData:data];
    return sendData;
}

    
#pragma mark -- GCDAsyncSocketDelegate

//连接服务器成功
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(nonnull NSString *)host port:(uint16_t)port {
    NSLog(@"%@----",host);
    NSLog(@"连接服务器成功");
    self.connectStatusL.text = @"已连接";
    self.connectStatusL.textColor = [UIColor blueColor];
    self.statusButton.selected = YES;
}
//读取进度 不包含结束段
- (void)socket:(GCDAsyncSocket *)sock didReadPartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
    
}

//发送数据的大小 可以用来检测数据是否发送完成
- (void)socket:(GCDAsyncSocket *)sock didWritePartialDataOfLength:(NSUInteger)partialLength tag:(long)tag {
//    CGFloat progress = [sock progressOfWriteReturningTag:&tag bytesDone:nil total:&(_length)];
//    NSLog(@"发送进度--%f",progress);
//    [SVProgressHUD showProgress:progress];
//    if (progress > 0.99) {
//        [SVProgressHUD dismiss];
//
//    }
}

//接收端收到消息
- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    NSLog(@"%s",__FUNCTION__);
    NSLog(@"总长度--%ld",data.length);
    NSLog(@"%@",sock.localHost);
    //解析传输头
    if (!_headerDict) {
        _headerDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"传输头--%@",_headerDict);
        if (!_headerDict) {
            NSLog(@"errer: 无头文件");
            return;
        }
        NSString *lengthStr = _headerDict[@"length"];
        //等待读取传输数据的长度
        [sock readDataToLength:lengthStr.integerValue withTimeout:-1 tag:0];
        return;
    }
    //判断接收的数据长度是否与头文件的一致
    NSString *lengthStr = _headerDict[@"length"];
    if (data.length != lengthStr.integerValue) {
        NSLog(@"文件错误");
        return;
    }
    NSString *type = _headerDict[@"type"];
    
    if ([type isEqualToString:@"reply"]) {
        NSString *info = _headerDict[@"info"];
        if (info.intValue == 0) {
            [SVProgressHUD showSuccessWithStatus:@"发送成功"];
        }else if (info.intValue == 1 || info.intValue == 2) {
            NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            [SVProgressHUD showErrorWithStatus:text];
        }
    }else if ([type isEqualToString:@"image"]) {
        UIImage *image = [UIImage imageWithData:data];
        self.imageView.image = image;
        NSLog(@"图片二进制长度--%lu",(unsigned long)data.length);
    }else if ([type isEqualToString:@"text"]) {
        NSString *info = _headerDict[@"info"];
        NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSString *texts = [NSString stringWithFormat:@"%@\n %@:%@", self.textView.text, info, text];
        NSLog(@"接收到的数据%@",text);
        self.textView.text = texts;
    }else {
        NSLog(@"%ld",data.length);
    }
    //等待读取下次的传输数据
    [sock readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:0];
    _headerDict = nil;
}

//断开服务器成功
-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err {
    NSLog(@"sock: %p",sock);
    NSLog(@"断开连接,断开原因: %@",err);
    
    
    self.connectStatusL.text = @"未连接";
    self.connectStatusL.textColor = [UIColor redColor];
    self.statusButton.selected = NO;
    self.pingL.text = @"ping:";
    //被动断开连接的话,就只关心跳包跳定时器
    [self.longConnectTimer invalidate];
    self.longConnectTimer = nil;
    self.imageView.image = nil;
    _headerDict = nil;
}


//- (void)viewWillAppear:(BOOL)animated {
//    [super viewWillAppear:animated];
//    NSString *str = @"ABCDEFG";
//    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
//    NSString *strData = [self DataToHexStr:data];
//    NSData *dataStr = [self HexStrToData:strData];
//    NSLog(@"%@---%@",data,str);
//
//    NSLog(@"%@---%@",strData,dataStr);
//
//}
//二进制数据转16进制字符串
- (NSString *)DataToHexStr:(NSData *)data {
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    
    return string;
}

//十六进制字符串转为二进制数据
- (NSData *)HexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    
    return hexData;
}

- (void)dealloc {
    self.clientSocket.delegate = nil;
    self.clientSocket = nil;
}

@end







